import React, { useState, useEffect } from "react";

// 把组件Test抽象成一个纯函数，纯函数中不能使用hook
const test = () => {
  let num = 0;

  const effect = () => {
    num += 1;
    const message = `现在的num值：${num}`;
    return function unmount() {
      console.log(message, num);
    };
  };

  return effect;
};

// 执行test，返回effect函数
const add = test();
// 执行effect函数，返回引用了message1的unmount函数
const unmount = add();
// 再次执行effect函数，返回引用了message2的unmount函数
add();
// message3
add();
// 执行unmount函数，这个函数被定义时，num的值是1
unmount();

// react hook与闭包经典的坑
export const Test = () => {
  const [num, setNum] = useState(0);

  // 无论按钮加到几，console.log输出的永远是0
  const add = () => setNum(num + 1);

  // 每次设置num值都清掉旧的计时器，再重新定义一个新的定时器
  // useEffect(() => {
  //   const t1 = setInterval(() => {
  //     console.log('num的值：', num);
  //   }, 1000);

  //   return () => {
  //     clearInterval(t1);
  //   }
  // // eslint-disable-next-line react-hooks/exhaustive-deps
  // }, [num]);

  useEffect(() => {
    // 会形成闭包
    return () => {
      // console.log("卸载时的值：", num);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [num]);

  return (
    <div>
      <button onClick={add}>add</button>
      <p>number: {num}</p>
    </div>
  );
};

/**
 * 理解完test后，再看Test组件
 *
 * useEffect()的代码只有在组件加载时被执行一次，
 * 所以 return () => {} 里面会形成一个闭包，它的作用域里面的num就是组件加载时num的值（useState初始化的值）
 * 所以之后无论点击按钮多少次，num的值一直是0
 * 那么如何才能让 return () => {} 中能拿到最新的num值呢？
 * 方法一：将num加到useEffect的第二个参数数组中，那么每当num变化时，return () => {}都会被重新定义一次，这样就能拿到最新的值
 *
 */
